package com.m.job.server.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.client.job.core.constant.JobInstanceStatus;
import com.client.job.core.model.MJob;
import com.client.job.core.model.MJobInstance;
import com.m.job.compents.JobAndInstanceCompent;
import com.m.job.server.mapper.MJobInstanceMapper;
import com.m.job.server.mapper.MJobMapper;
import com.m.job.server.model.MJobInstanceDto;
import com.m.job.server.service.MJobInstanceService;
import com.m.utils.IdUtil;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 任务机器Service
 * 
 * @author monxz
 * @version 2021-07-18
 */
@Service
@Transactional
public class MJobInstanceServiceImpl implements MJobInstanceService {

	@Autowired
	private MJobInstanceMapper jobMachineMapper;

	@Autowired
	private MJobMapper mJobMapper;

	@Autowired
	private JobAndInstanceCompent jobInstanceCompent;

	@Override
	public MJobInstanceDto getJobInstanceById(String mechineId) {
		return jobMachineMapper.get(mechineId);
	}

	@Override
	public List<MJobInstanceDto> findJobMachineList(MJobInstanceDto mJobInstanceDto) {
		return jobMachineMapper.getList(mJobInstanceDto);
	}

	@Override
	public void delFormDb(String mechineId) {
		jobMachineMapper.delete(mechineId);
	}

	

	@Override
	public void stopJobInstance(List<String> ids) throws Exception {
		// 根据Ids查询出所有的实例
		List<MJobInstance> instalceList = jobMachineMapper.getListByIdList(ids,JobInstanceStatus.JOB_RUNNING.getStatus());
		jobMachineMapper.updateJobStatusByIdList(ids, JobInstanceStatus.JOB_STOPING.getStatus(),null);
		// 根据JobId分组
		Map<String, List<MJobInstance>> jobIdMap = instalceList.stream()
				.collect(Collectors.groupingBy(MJobInstance::getJobId));
		// 根据分组的JobId查询
		List<MJob> list = new ArrayList<>();
		List<MJobInstance> updCounts = new ArrayList<>();
		List<MJob> delMjobList = new ArrayList<>();
		for (Entry<String, List<MJobInstance>> e : jobIdMap.entrySet()) {
			MJob mjob = mJobMapper.get(e.getKey());
			List<MJobInstance>  delList =     e.getValue().stream().filter(o -> o.getJobStatus() == JobInstanceStatus.JOB_RUNNING.getStatus() &&
					o.getServerStatus() == JobInstanceStatus.SERVER_RUNNING.getStatus() )
					.collect(Collectors.toList());
			if (delList != null && !delList.isEmpty()) {
				mjob.setAppCounts(mjob.getAppCounts() - delList.size());
				mJobMapper.lessAppCounts(mjob.getJobId(), delList.size());
				// 通知删除
				delMjobList.add(mjob);					
				// 根据当前JobId查询出运行中的实例
				List<MJobInstanceDto> sameTypeList = jobMachineMapper.getListByJobCode(mjob.getJobCode(),
						JobInstanceStatus.JOB_RUNNING.getStatus(), JobInstanceStatus.SERVER_RUNNING.getStatus());
				if (sameTypeList != null && !sameTypeList.isEmpty()) {
					Integer sort = 0;
					list.add(mjob);
					for (MJobInstanceDto mi : sameTypeList) {
						mi.setSort(sort);
						sort++;
						jobMachineMapper.update(mi);
						updCounts.add(mi);
					}
				}

			}
		}
		
		jobInstanceCompent.stopInstances(delMjobList, instalceList, list, updCounts);	
	}

	@Override
	public void startJobInstance(List<String> ids) throws Exception {
		// 根据Ids查询出所有的实例
		List<MJobInstance> instalceList = jobMachineMapper.getListByIdList(ids,JobInstanceStatus.JOB_STOPING.getStatus());
		jobMachineMapper.updateJobStatusByIdList(ids, JobInstanceStatus.JOB_RUNNING.getStatus(),null);
		// // 根据JobId分组
		Map<String, List<MJobInstance>> jobIdMap = instalceList.stream()
				.collect(Collectors.groupingBy(MJobInstance::getJobId));
		
		List<MJob> list = new ArrayList<>();
		List<MJobInstance> updCounts = new ArrayList<>();
		
		for(Entry<String, List<MJobInstance>> e : jobIdMap.entrySet()) {
			MJob mjob = mJobMapper.get(e.getKey());
			List<MJobInstance>  startList =     e.getValue().stream().filter(o -> o.getJobStatus() == JobInstanceStatus.JOB_STOPING.getStatus() &&
					o.getServerStatus() == JobInstanceStatus.SERVER_RUNNING.getStatus() )
					.collect(Collectors.toList());
			if(startList != null && !startList.isEmpty()) {
				mjob.setAppCounts(mjob.getAppCounts() + startList.size());
				mJobMapper.lessAppCounts(mjob.getJobId(),  -startList.size());
				// 根据当前JobId查询出运行中的实例
				List<MJobInstanceDto> sameTypeList = jobMachineMapper.getListByJobCode(mjob.getJobCode(),
						JobInstanceStatus.JOB_RUNNING.getStatus(), JobInstanceStatus.SERVER_RUNNING.getStatus());
				if (sameTypeList != null && !sameTypeList.isEmpty()) {
					Integer sort = 0;
					for (MJobInstanceDto mi : sameTypeList) {
						mi.setSort(sort);
						sort++;
						jobMachineMapper.update(mi);
						updCounts.add(mi);
					}
					list.add(mjob);				
				}
				
			}
		}		
		jobInstanceCompent.startInstances(instalceList, list, updCounts);		
	}

	@Override
	public void copyJobInstance(MJobInstanceDto mJobInstanceDto) throws Exception {
		MJobInstance cm = jobMachineMapper.get(mJobInstanceDto.getMachineId());
		MJobInstanceDto search = new MJobInstanceDto();
		search.setJobId(cm.getJobId());
		search.setJobStatus(JobInstanceStatus.JOB_RUNNING.getStatus());
		search.setServerStatus(JobInstanceStatus.SERVER_RUNNING.getStatus());
		List<MJobInstanceDto> installList = jobMachineMapper.getExctList(search);
		// 修改当前
		mJobInstanceDto.setJobStatus(JobInstanceStatus.JOB_RUNNING.getStatus());
		mJobInstanceDto.setSort(installList == null ? 0 : installList.size());
		mJobInstanceDto.setMachineId(IdUtil.genId());
		jobMachineMapper.insert(mJobInstanceDto);
		mJobMapper.lessAppCounts(mJobInstanceDto.getJobId(), -1);
		MJob mJob = mJobMapper.get(mJobInstanceDto.getJobId());
		installList.add(mJobInstanceDto);
		jobInstanceCompent.copyInstance(mJobInstanceDto,mJob, MJobInstanceDto.dtoListToPoList( installList));
	}
	
	@SuppressWarnings("static-access")
	@Override
	public void addJobInstance(MJobInstanceDto mJobInstanceDto) throws Exception {
		//运行中的实例
		List<MJobInstanceDto> runList = jobMachineMapper.getListByJobIds(Arrays.asList(mJobInstanceDto.getJobId()),
				JobInstanceStatus.SERVER_RUNNING.getStatus(),
				JobInstanceStatus.JOB_RUNNING.getStatus());
		mJobInstanceDto.setSort(runList.size());
		mJobInstanceDto.setMachineId(IdUtil.genId());
		mJobInstanceDto.setJobStatus(JobInstanceStatus.JOB_RUNNING.getStatus());
		mJobInstanceDto.setServerStatus(JobInstanceStatus.SERVER_RUNNING.getStatus());
		jobMachineMapper.insert(mJobInstanceDto);
		runList.add(mJobInstanceDto);
		mJobMapper.lessAppCounts(mJobInstanceDto.getJobId(), -1);
		jobInstanceCompent.addNewInstance(
				mJobInstanceDto.dtoToPo( mJobInstanceDto), 
				mJobMapper.get(mJobInstanceDto.getJobId()), 
				mJobInstanceDto.dtoListToPoList( runList));
		
	}



	

}